home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Format Collection 21
/
PC Format CD-ROM Collection 21 (1995-12)(Future Publishing)(GB)[issue 51].iso
/
resource
/
numpic.poc
< prev
next >
Wrap
Text File
|
1992-09-11
|
16KB
|
550 lines
/**
**
** NUMPIC.POC - Ways to convert a numbered sequence of picture files
** to a flic and back. Also a way to delete the numbered sequence of
** pictures when you're done.
**
**/
#pragma poco library "pdracces.poe" // extended picture I/O library
#include <errcodes.h>
#define NO_DIALOG 0 // Parameter to pdraccess options routine
#define DO_DIALOG 1 // Parameter to pdraccess options routine
/*----------------------------------------------------------------------------
* dialog strings, menu choices, etc...
*--------------------------------------------------------------------------*/
char basename_prompt[] = "Base name of numbered pictures?";
char delete_basename_prompt[] = "Base name of numbered files?";
char rgbname_prompt[] = "Name of (RGB) pic to load?";
char dirfile_prompt[] = "Choose file of the correct type in directory:";
char replace_changes_prompt[] = "Okay to discard current flic?\n"
"(You have %d unsaved changes)"
;
char change_flic_size_prompt[] = "Force flic size to picture size?\n\n"
"(Current flic size is %d x %d,\n"
"input picture size is %d x %d.)\n"
;
char menu_prompt[] = "Convert between Flic and Pictures";
char *menu_choices[] =
{
" Save Flic as Pics",
" Load Pics as Flic",
" Delete Numbered Files",
" Load Single (RGB) Pic",
" Load All in Directory",
" Exit",
};
enum {MU_EXIT, MU_SAVE, MU_LOAD, MU_DELETE, MU_LOAD1, MU_LOAD_DIR};
char load_prompt[] = "Found %d pictures.\n\n"
"The pictures may be appended to the end of the "
"current flic, inserted following the current frame, "
"or entirely replace the current flic. "
"\n\n"
"Please select load option:\n"
;
char *load_choices[] = {"Append", "Insert", "Replace", "Cancel"};
enum {LOAD_APPEND=1, LOAD_INSERT, LOAD_REPLACE, LOAD_CANCEL};
char pdr_prompt[] = "Please select output format:";
char *pdr_choices[] = {"GIF", "PCX", "TIFF", "Targa", "Macintosh Pict",
"Windows Bitmap", "Cancel"};
char *pdr_names[] = {"GIF.PDR", "PCX.PDR", "TIFF.PDR", "TARGA.PDR",
"PICT.PDR", "BMP.PDR"};
char *pdr_suffixes[] = {".GIF", ".PCX", ".TIF", ".TGA", ".PCT", ".BMP"};
char *start_of_final_digits(char *pt)
/***********************************************************************
* returns pointer to the start of the ending number in the string.
***********************************************************************/
{
char c;
int len;
int i;
i = len = strlen(pt);
pt += len;
while (--i >= 0) {
c = *(--pt);
if (!(c >= '0' && c <= '9'))
return(pt+1);
}
return pt;
}
int get_num_name(char *name)
/***********************************************************************
* Return the number embedded in the "file" portion of a file-name
* (as opposed to the directory or the suffix.) Return -1 if none.
***********************************************************************/
{
char *pt;
char dev[4],dir[70],file[10],suff[5];
fnsplit(name,dev,dir,file,suff);
if ((pt = start_of_final_digits(file)) == file)
return(-1);
return(atoi(pt));
}
int count_digits(int num)
/***********************************************************************
* Return number of digits (base 10) in number.
***********************************************************************/
{
int digits = 1;
while (num > 10) {
++digits;
num /= 10;
}
return(digits);
}
void make_num_name(char *buf, char *name, int num, int digits)
/***********************************************************************
* Given a full file name (device, path, file, suffix), a number,
* and a minimum count of digits, make a name with the number
* embedded in the last parts of the 'file' portion of the name.
* Parameters:
* char *buf; where to put the numbered name
* char *name; the original name.
* int num; the number.
* int digits; minimum amount of digits to use.
* Example:
* make_num_name(buf, "c:\pics\sample.gif", 16, 3)
* leaves "c:\pics\sampl016.gif" in buf.
***********************************************************************/
{
char dev[4],dir[70],file[10],suff[5];
char nfile[10];
int diglen;
char *pt;
fnsplit(name,dev,dir,file,suff); // split file into component parts
if (count_digits(num)>digits) // if number too big override digits
digits = count_digits(num);
pt = start_of_final_digits(file);
diglen = strlen(pt); // find out how many digits already in file name
if (diglen < digits) { // if less than needed truncate file name
file[8-digits] = 0;
diglen = digits;
} else { // Otherwise truncate at first digit
*pt = 0;
}
sprintf(nfile,"%s%0*d", file, diglen, num);
fnmerge(buf,dev,dir,nfile,suff);
}
ErrCode set_up_for_output(char *name)
/***********************************************************************
* find and load the pdr to handle the output format, get output options.
* we try to figure out the pdr name from the basename filetype, but
* if that doesn't work (eg, if there is no suffix on the basename),
* we prompt the user for the output format using Qmenu.
* after a pdr is loaded to handle the output, we check whether output
* options are supported by the pdr, and if so, we call the pdr's
* options preset dialog.
**********************************************************************/
{
ErrCode err;
int thechoice;
char *pdrname;
char dev[4],dir[70],file[10],suff[5];
if (Success > (err = PicDriverFindLoad(name))) {
thechoice = Qmenu(pdr_choices, Array_els(pdr_choices), pdr_prompt);
if (--thechoice < 0) // convert choice # to array index,
return Err_abort; // if < 0, user picked Cancel or right-clicked
if (Success > (err = PicDriverLoad(pdr_names[thechoice]))) {
return Qerror(err, "Cannot load picture driver %s",pdr_names[thechoice]);
}
/* If they've picked a driver from list, force suffix to match. */
fnsplit(name,dev,dir,file,suff); // split file into component parts
fnmerge(name,dev,dir,file,pdr_suffixes[thechoice]);
}
if (PicPdrHasOptions()) {
if (Success > (err = PicPdrOptionsPreset(DO_DIALOG, 0)))
return err;
}
return Success;
}
void save_pics(char *name)
/***********************************************************************
* Save one picture for each frame in current flic.
***********************************************************************/
{
int i;
int count;
char nbuf[PATH_SIZE];
char suffix[5];
ErrCode err;
int min, max;
// Go load the appropriate pdr for outputting the pictures...
if (Success > (err = set_up_for_output(name))) {
return;
}
// Set up the loop control...
count = GetFrameCount();
if ((min = get_num_name(name)) < 0)
min = 1;
max = min + count - 1;
// Output the pictures...
for (i = min; i <= max; ++i) {
make_num_name(nbuf,name,i,count_digits(max)); // make up file name
printf("Saving %s", nbuf); // Put up status line
if (Success > (err = PicSave(nbuf, NULL))) {
Qerror(err, "Couldn't save %s", nbuf);
return;
}
NextFrame();
}
unprintf(); // Get rid of status line
}
Boolean fexists(char *name)
/***********************************************************************
* See whether a file exists.
***********************************************************************/
{
FILE *f;
if ((f = fopen(name, "rb")) != NULL) {
fclose(f);
return TRUE;
}
else
return FALSE;
}
int count_files(char *base_name)
/***********************************************************************
* Count up the number of files starting at base_name and
* numbered sequentially.
***********************************************************************/
{
char nbuf[PATH_SIZE];
int count = 0;
int base = get_num_name(base_name);
for (;;)
{
make_num_name(nbuf, base_name,base+count,0);
if (!fexists(nbuf))
break;
++count;
}
return count;
}
Boolean report_about_error(ErrCode err, char *name, int cur_pos, int total)
/***********************************************************************
* Tell user had error and ask if want to continue.
***********************************************************************/
{
int temp;
Qerror(err, "Can't load %s (%d of %d)", name, cur_pos+1, total);
temp = total - cur_pos - 1;
if (temp > 0)
{
if (!Qquestion("Continue loading other %d Pics?", temp))
return FALSE;
}
return TRUE;
}
void load_pics(char *base_name)
/***********************************************************************
* Load up a bunch of consecutively numbered files into the flic.
***********************************************************************/
{
int i;
int count;
int curframe;
int thechoice;
char nbuf[PATH_SIZE];
int base;
int flicw, flich;
int picw, pich, picdepth;
ErrCode err;
int temp;
base = get_num_name(base_name);
count = count_files(base_name);
// Get the picture size info for the first pic. This ensures that the
// file exists, and that a pdr can be found by the pdraccess routines to
// process the pictures.
if (Success > (err = PicGetSize(base_name, &picw, &pich, &picdepth))) {
Qerror(err, "Cannot load %s", base_name);
return;
}
// Tell the user how many pictures we found to be loaded, and ask for
// the input option (replace/append/insert). If the replace option is
// choosen, allow the user to change the size of the new flic, if the size
// of the pictures differs from the current flic size.
thechoice = Qchoice(load_choices, Array_els(load_choices), load_prompt, count);
switch (thechoice) {
case LOAD_REPLACE:
if (0 != (i = GetChangeCount())) {
if (!Qquestion(replace_changes_prompt, i))
return;
}
GetSize(&flicw, &flich);
if (flicw != picw || flich != pich) {
if (Qquestion(change_flic_size_prompt,flicw,flich,picw,pich)) {
flicw = picw;
flich = pich;
}
}
ResizeReset(flicw, flich);
SetFrameCount(count);
break;
case LOAD_APPEND:
SetFrame(GetFrameCount()-1); // move to end of flic
/* fall thru */
case LOAD_INSERT:
InsertFrames(count); // insert enough frames for pics
NextFrame(); // move to first of inserted frames
break;
default:
return; // User selected Cancel or right-clicked
}
// If rgb/truecolor data was found in the picture, ask the user for the
// rgb processing option via the pdracces preset dialog. The choosen
// option will remain in effect throughout the load sequence.
if (picdepth > 8) {
if (Success > (err = PicRgbOptionsPreset(DO_DIALOG,0)))
return;
}
curframe = 1+GetFrame();
// Load the pictures...
for (i=0; i < count;) {
make_num_name(nbuf, base_name, base+i, 0);
printf("Loading %s into frame %d", nbuf, curframe);
if (Success > (err = PicLoad(nbuf,NULL))) {
if (!report_about_error(err, nbuf, i, count))
return;
}
if (++i < count) { // don't advance after last picture
NextFrame(); // (makes multiple insert sequences
++curframe; // easier for the user)
}
}
unprintf(); // all done, get rid of top status info line
}
void load_pic_list(char **list, int count)
/***********************************************************************
* Load a list of files into flic.
***********************************************************************/
{
Boolean got_rgb = FALSE;
char *name;
int picw, pich, picdepth;
int i;
ErrCode err;
SetFrameCount(count);
SetFrame(0);
for (i=0; i<count; ++i)
{
name = *list++;
/* First check to see if it's RGB */
if (Success > (err = PicGetSize(name, &picw, &pich, &picdepth))) {
Qerror(err, "Cannot load %s", name);
if (!report_about_error(err, name, i, count))
return;
} else {
/* If RGB (and haven't already) then query how to handle
* color reduction. */
if (picdepth > 8 && !got_rgb) {
if (Success > (err = PicRgbOptionsPreset(DO_DIALOG,0)))
return;
got_rgb = TRUE;
}
if (Success > (err = PicLoad(name,NULL))) {
Qerror(err, "Cannot load %s", name);
if (!report_about_error(err, name, i, count))
return;
}
}
NextFrame();
}
}
void load_dir(char *base_name)
/***********************************************************************
* Load a whole directory into flic.
***********************************************************************/
{
char dev[4],dir[70],file[10],suff[5];
char wild[10];
char old_dir[80];
char **file_list;
int file_count;
fnsplit(base_name, dev, dir, file, suff);
fnmerge(base_name, dev, dir, "", "");
/* base name is now dir only. */
GetDir(old_dir);
SetDir(base_name);
sprintf(wild, "*%s", suff);
if ((file_count = DirList(&file_list, wild, FALSE)) > 0)
{
load_pic_list(file_list, file_count);
FreeDirList(&file_list);
}
SetDir(old_dir);
}
void delete_files(char *base_name)
/***********************************************************************
* Delete a bunch of consecutively numbered files.
***********************************************************************/
{
char nbuf[PATH_SIZE];
int count;
int i;
int base;
base = get_num_name(base_name);
count = count_files(base_name);
// make extra sure the user wants to do this...
if (!Qquestion("Delete numbered files starting with %s ???", base_name))
return;
if (!Qquestion("Are you sure you want to delete all %d"
" files starting with:\n %s?", count, base_name))
return;
// okay, go for it.
for (i=0; i < count; ++i)
{
make_num_name(nbuf, base_name, base+i, 0);
DosDelete(nbuf);
}
}
Boolean do_one_set(char *base_name)
/**********************************************************************
* Put up main program menu and respond to choices. Return FALSE if
* user selects Exit, TRUE after other commands.
**********************************************************************/
{
int choice;
ErrCode err;
char *what;
char *qfile_header = basename_prompt;
choice = Qmenu(menu_choices, Array_els(menu_choices), menu_prompt);
if (choice == MU_LOAD1) /* It's pretty easy to load one pic. */
{
if (Qfile(".TGA;.TIF", "Load",
base_name, base_name, FALSE, rgbname_prompt))
{
if (Success > (err = PicLoad(base_name,NULL)))
Qerror(err, "Can't load %s", base_name);
}
}
else
{
// Figure out what to put on the file selector action button...
switch (choice)
{
case MU_SAVE:
what = "Save";
break;
case MU_LOAD:
what = "Load";
break;
case MU_DELETE:
what = "Delete";
qfile_header = delete_basename_prompt;
break;
case MU_LOAD_DIR:
what = "Load Dir";
qfile_header = dirfile_prompt;
break;
default:
return FALSE; // User has chosen Exit or right-clicked.
}
// Ask user for the base file name...
if (!Qfile(".*", what, base_name, base_name, FALSE, qfile_header))
return TRUE; // Quit this command, but not program.
// Invoke the requested action...
switch (choice)
{
case MU_SAVE:
save_pics(base_name);
break;
case MU_LOAD:
load_pics(base_name);
break;
case MU_DELETE:
delete_files(base_name);
break;
case MU_LOAD_DIR:
load_dir(base_name);
break;
}
}
return TRUE;
}
void main(void)
/***********************************************************************
* Call menu routine above until Exit/Cancel.
**********************************************************************/
{
static char last_path[PATH_SIZE] = "";
GlobalVarGet("numpic_lastpath",last_path);
while (do_one_set(last_path))
;
GlobalVarSet("numpic_lastpath",last_path);
}